
using Microsoft.EntityFrameworkCore;
using UniversalAdmin.Domain.Entities;
using UniversalAdmin.Domain.Repositories;
using UniversalAdmin.Infrastructure.Data.Contexts;
using UniversalAdmin.Domain.Entities.App;

namespace UniversalAdmin.Infrastructure.Repositories;

public class EfRepositories<T> : IRepositories<T> where T : EntityBase
{
    private readonly AdminDbContext _db;

    private readonly DbSet<T> _tb;

    public IQueryable<T> Table => _tb.AsQueryable();

    public EfRepositories(AdminDbContext db)
    {
        _db = db;
        _tb = db.Set<T>();
    }

    public async Task<T> CreateAsync(T entity)
    {
        var obj = await _tb.AddAsync(entity);
        await _db.SaveChangesAsync();
        return obj.Entity;
    }

    public async Task DeleteAsync(T entity)
    {
        entity.IsDeleted = true;
        await UpdateAsync(entity);
    }
    public async Task<IEnumerable<T>> GetAllAsync()
    {
        if (typeof(T) == typeof(User))
        {
            var userDbSet = _db.Set<User>();
            var users = await userDbSet
                .Include(u => u.Roles)
                .ToListAsync();
            return users.Cast<T>();
        }
        
        var list = await _tb.ToListAsync();
        return list;
    }

    public async Task<T?> GetByIdAsync(Guid id)
    {
        if (typeof(T) == typeof(User))
        {
            var userDbSet = _db.Set<User>();
            var user = await userDbSet
                .Include(u => u.Roles)
                .FirstOrDefaultAsync(u => u.Id == id);
            return user as T;
        }
        
        var list = await _tb.FindAsync(id);
        return list;
    }

    public async Task UpdateAsync(T entity)
    {
        _tb.Update(entity);
        await _db.SaveChangesAsync();
    }

    // public async Task<IQueryable<T>> GetPagedAsync(int pageIndex, int pageSize)
    // {
    //     var list = await _tb.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();
    //     return list.AsQueryable();
    // }

    public async Task<IQueryable<T>> GetPagedAsync(int pageIndex, int pageSize)
    {
        if (typeof(T) == typeof(User))
        {
            var userDbSet = _db.Set<User>();
            var users = await userDbSet
                .Include(u => u.Roles)
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize)
                .ToListAsync();
            return users.Cast<T>().AsQueryable();
        }
        
        return await Task.FromResult(_tb.Skip((pageIndex - 1) * pageSize).Take(pageSize));
    }
    public async Task<long> GetCountAsync()
    {
        return await _tb.LongCountAsync();
    }
    
    public async Task<T?> GetByUsernameAsync(string username)
    {
        // 这个方法主要用于User实体，其他实体类型会返回null
        if (typeof(T) == typeof(User))
        {
            var userDbSet = _db.Set<User>();
            var user = await userDbSet
                .Include(u => u.Roles)
                .FirstOrDefaultAsync(u => u.Username == username);
            return user as T;
        }
        return null;
    }
}